/*
 * Copyright 2002-2020 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.bind.annotation;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import org.springframework.core.annotation.AliasFor;
import org.springframework.web.cors.CorsConfiguration;

/**
 * Annotation for permitting cross-origin requests on specific handler classes
 * and/or handler methods. Processed if an appropriate {@code HandlerMapping}
 * is configured.
 *
 * <p>Both Spring Web MVC and Spring WebFlux support this annotation through the
 * {@code RequestMappingHandlerMapping} in their respective modules. The values
 * from each type and method level pair of annotations are added to a
 * {@link CorsConfiguration} and then default values are applied via
 * {@link CorsConfiguration#applyPermitDefaultValues()}.
 *
 * <p>The rules for combining global and local configuration are generally
 * additive -- e.g. all global and all local origins. For those attributes
 * where only a single value can be accepted such as {@code allowCredentials}
 * and {@code maxAge}, the local overrides the global value.
 * See {@link CorsConfiguration#combine(CorsConfiguration)} for more details.
 *
 * @author Russell Allen
 * @author Sebastien Deleuze
 * @author Sam Brannen
 * @since 4.2
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
// 允许对特定处理程序类和/或处理程序方法的跨域请求的注释。如果配置了适当的HandlerMapping ，则进行处理。
// Spring Web MVC 和 Spring WebFlux 都通过各自模块中的RequestMappingHandlerMapping支持此注解。
// 每个类型和方法级别的注释对的值被添加到CorsConfiguration ，然后通过CorsConfiguration.applyPermitDefaultValues()应用默认值。
// 组合全局和局部配置的规则通常是相加的——例如所有全局和所有局部源。
// 对于那些只能接受单个值的属性，例如allowCredentials和maxAge ，本地会覆盖全局值。
// 有关更多详细信息，请参阅CorsConfiguration.combine(CorsConfiguration) 。
public @interface CrossOrigin {

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	String[] DEFAULT_ORIGINS = {"*"};

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	String[] DEFAULT_ALLOWED_HEADERS = {"*"};

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	boolean DEFAULT_ALLOW_CREDENTIALS = false;

	/** @deprecated as of Spring 5.0, in favor of {@link CorsConfiguration#applyPermitDefaultValues} */
	@Deprecated
	long DEFAULT_MAX_AGE = 1800;


	/**
	 * Alias for {@link #origins}.
	 */
	@AliasFor("origins")
	String[] value() default {};

	/**
	 * The list of allowed origins that be specific origins, e.g.
	 * {@code "https://domain1.com"}, or {@code "*"} for all origins.
	 * <p>A matched origin is listed in the {@code Access-Control-Allow-Origin}
	 * response header of preflight actual CORS requests.
	 * <p>By default all origins are allowed.
	 * <p><strong>Note:</strong> CORS checks use values from "Forwarded"
	 * (<a href="https://tools.ietf.org/html/rfc7239">RFC 7239</a>),
	 * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers,
	 * if present, in order to reflect the client-originated address.
	 * Consider using the {@code ForwardedHeaderFilter} in order to choose from a
	 * central place whether to extract and use, or to discard such headers.
	 * See the Spring Framework reference for more on this filter.
	 * @see #value
	 */
	// 特定来源的允许来源列表，例如"https://domain1.com"或所有来源的"*" 。
	// 匹配的来源列在预检实际 CORS 请求的Access-Control-Allow-Origin响应标头中。
	// 默认情况下，所有来源都是允许的。
	// 注意： CORS 检查使用来自“Forwarded”（ RFC 7239  ）、“X-Forwarded-Host”、“X-Forwarded-Port”和“X-Forwarded-Proto”标头（如果存在）的值，
	// 以反映客户端- 始发地址。
	// 考虑使用ForwardedHeaderFilter以便从中心位置选择是提取和使用还是丢弃此类标头。
	// 有关此过滤器的更多信息，请参阅 Spring Framework 参考。
	@AliasFor("value")
	String[] origins() default {};

	/**
	 * The list of request headers that are permitted in actual requests,
	 * possibly {@code "*"}  to allow all headers.
	 * <p>Allowed headers are listed in the {@code Access-Control-Allow-Headers}
	 * response header of preflight requests.
	 * <p>A header name is not required to be listed if it is one of:
	 * {@code Cache-Control}, {@code Content-Language}, {@code Expires},
	 * {@code Last-Modified}, or {@code Pragma} as per the CORS spec.
	 * <p>By default all requested headers are allowed.
	 */
	// 实际请求中允许的请求标头列表，可能是"*"以允许所有标头。
	// 预检请求的Access-Control-Allow-Headers响应标头中列出了允许的标头。
	// 如果标头名称是以下之一，则不需要列出标头名称： Cache-Control 、 Content-Language 、 Expires 、 Last-Modified或Pragma根据 CORS 规范。
	// 默认情况下，允许所有请求的标头。
	String[] allowedHeaders() default {};

	/**
	 * The List of response headers that the user-agent will allow the client
	 * to access on an actual response, other than "simple" headers, i.e.
	 * {@code Cache-Control}, {@code Content-Language}, {@code Content-Type},
	 * {@code Expires}, {@code Last-Modified}, or {@code Pragma},
	 * <p>Exposed headers are listed in the {@code Access-Control-Expose-Headers}
	 * response header of actual CORS requests.
	 * <p>The special value {@code "*"} allows all headers to be exposed for
	 * non-credentialed requests.
	 * <p>By default no headers are listed as exposed.
	 */
	// 用户代理将允许客户端访问实际响应的响应头列表，而不是“简单”头，即Cache-Control 、 Content-Language 、 Content-Type 、 Expires 、
	// Last-Modified或Pragma ，
	// 公开的标头列在实际 CORS 请求的Access-Control-Expose-Headers响应标头中。
	// 特殊值"*"允许为非凭据请求公开所有标头。
	// 默认情况下，没有标头被列为公开。
	String[] exposedHeaders() default {};

	/**
	 * The list of supported HTTP request methods.
	 * <p>By default the supported methods are the same as the ones to which a
	 * controller method is mapped.
	 */
	// 支持的 HTTP 请求方法列表。
	// 默认情况下，支持的方法与控制器方法映射到的方法相同。
	RequestMethod[] methods() default {};

	/**
	 * Whether the browser should send credentials, such as cookies along with
	 * cross domain requests, to the annotated endpoint. The configured value is
	 * set on the {@code Access-Control-Allow-Credentials} response header of
	 * preflight requests.
	 * <p><strong>NOTE:</strong> Be aware that this option establishes a high
	 * level of trust with the configured domains and also increases the surface
	 * attack of the web application by exposing sensitive user-specific
	 * information such as cookies and CSRF tokens.
	 * <p>By default this is not set in which case the
	 * {@code Access-Control-Allow-Credentials} header is also not set and
	 * credentials are therefore not allowed.
	 */
	// 浏览器是否应将凭据（例如 cookie 以及跨域请求）发送到带注释的端点。配置的值在预检请求的Access-Control-Allow-Credentials响应标头上设置。
	// 注意：请注意，此选项会与配置的域建立高度信任，并且还会通过暴露敏感的用户特定信息（例如 cookie 和 CSRF 令牌）增加 Web 应用程序的表面攻击。
	// 默认情况下，未设置此项，在这种情况下，也未设置Access-Control-Allow-Credentials标头，因此不允许使用凭据。
	String allowCredentials() default "";

	/**
	 * The maximum age (in seconds) of the cache duration for preflight responses.
	 * <p>This property controls the value of the {@code Access-Control-Max-Age}
	 * response header of preflight requests.
	 * <p>Setting this to a reasonable value can reduce the number of preflight
	 * request/response interactions required by the browser.
	 * A negative value means <em>undefined</em>.
	 * <p>By default this is set to {@code 1800} seconds (30 minutes).
	 */
	// 预检响应的缓存持续时间的最长期限（以秒为单位）。
	// 此属性控制预检请求的Access-Control-Max-Age响应标头的值。
	// 将此设置为合理的值可以减少浏览器所需的预检请求/响应交互的数量。负值表示未定义。
	// 默认情况下，这设置为1800秒（30 分钟）。
	long maxAge() default -1;

}
